home *** CD-ROM | disk | FTP | other *** search
/ Windows Game Programming for Dummies (2nd Edition) / WinGamProgFD.iso / pc / DirectX SDK / DXSDK / bin / DXUtils / AppWizard / DXAppwiz.awx / TEMPLATE / D3DFILE.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  2001-10-25  |  23.6 KB  |  810 lines

  1. //-----------------------------------------------------------------------------
  2. // File: D3DFile.cpp
  3. //
  4. // Desc: Support code for loading DirectX .X files.
  5. //-----------------------------------------------------------------------------
  6. #define STRICT
  7. $$IF(DLG)
  8. #include "stdafx.h"
  9. $$ENDIF
  10. #include <tchar.h>
  11. #include <stdio.h>
  12. #include <d3d8.h>
  13. #include <d3dx8.h>
  14. #include <dxfile.h>
  15. #include <rmxfguid.h>
  16. #include <rmxftmpl.h>
  17. #include "D3DFile.h"
  18. #include "DXUtil.h"
  19.  
  20.  
  21.  
  22.  
  23. //-----------------------------------------------------------------------------
  24. // Name:
  25. // Desc:
  26. //-----------------------------------------------------------------------------
  27. CD3DMesh::CD3DMesh( TCHAR* strName )
  28. {
  29.     _tcscpy( m_strName, strName );
  30.     m_pSysMemMesh        = NULL;
  31.     m_pLocalMesh         = NULL;
  32.     m_dwNumMaterials     = 0L;
  33.     m_pMaterials         = NULL;
  34.     m_pTextures          = NULL;
  35.     m_bUseMaterials      = TRUE;
  36. }
  37.  
  38.  
  39.  
  40.  
  41. //-----------------------------------------------------------------------------
  42. // Name:
  43. // Desc:
  44. //-----------------------------------------------------------------------------
  45. CD3DMesh::~CD3DMesh()
  46. {
  47.     Destroy();
  48. }
  49.  
  50.  
  51.  
  52.  
  53. //-----------------------------------------------------------------------------
  54. // Name:
  55. // Desc:
  56. //-----------------------------------------------------------------------------
  57. HRESULT CD3DMesh::Create( LPDIRECT3DDEVICE8 pd3dDevice, TCHAR* strFilename )
  58. {
  59.     TCHAR        strPath[MAX_PATH];
  60.     CHAR         strPathANSI[MAX_PATH];
  61.     LPD3DXBUFFER pAdjacencyBuffer = NULL;
  62.     LPD3DXBUFFER pMtrlBuffer = NULL;
  63.     HRESULT      hr;
  64.  
  65.     // Find the path for the file, and convert it to ANSI (for the D3DX API)
  66.     DXUtil_FindMediaFile( strPath, strFilename );
  67.     DXUtil_ConvertGenericStringToAnsi( strPathANSI, strPath );
  68.  
  69.     // Load the mesh
  70.     if( FAILED( hr = D3DXLoadMeshFromX( strPathANSI, D3DXMESH_SYSTEMMEM, pd3dDevice, 
  71.                                         &pAdjacencyBuffer, &pMtrlBuffer, 
  72.                                         &m_dwNumMaterials, &m_pSysMemMesh ) ) )
  73.     {
  74.         return hr;
  75.     }
  76.  
  77.     // Optimize the mesh for performance
  78.     if( FAILED( hr = m_pSysMemMesh->OptimizeInplace(
  79.                         D3DXMESHOPT_COMPACT | D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_VERTEXCACHE,
  80.                         (DWORD*)pAdjacencyBuffer->GetBufferPointer(), NULL, NULL, NULL ) ) )
  81.     {
  82.         SAFE_RELEASE( pAdjacencyBuffer );
  83.         SAFE_RELEASE( pMtrlBuffer );
  84.         return hr;
  85.     }
  86.  
  87.     // Get material info for the mesh
  88.     // Get the array of materials out of the buffer
  89.     if( pMtrlBuffer && m_dwNumMaterials > 0 )
  90.     {
  91.         // Allocate memory for the materials and textures
  92.         D3DXMATERIAL* d3dxMtrls = (D3DXMATERIAL*)pMtrlBuffer->GetBufferPointer();
  93.         m_pMaterials = new D3DMATERIAL8[m_dwNumMaterials];
  94.         m_pTextures  = new LPDIRECT3DTEXTURE8[m_dwNumMaterials];
  95.  
  96.         // Copy each material and create its texture
  97.         for( DWORD i=0; i<m_dwNumMaterials; i++ )
  98.         {
  99.             // Copy the material
  100.             m_pMaterials[i]         = d3dxMtrls[i].MatD3D;
  101.             m_pMaterials[i].Ambient = m_pMaterials[i].Diffuse;
  102.             m_pTextures[i]          = NULL;
  103.  
  104.             // Create a texture
  105.             if( d3dxMtrls[i].pTextureFilename )
  106.             {
  107.                 TCHAR strTexture[MAX_PATH];
  108.                 TCHAR strTextureTemp[MAX_PATH];
  109.                 DXUtil_ConvertAnsiStringToGeneric( strTextureTemp, d3dxMtrls[i].pTextureFilename );
  110.                 DXUtil_FindMediaFile( strTexture, strTextureTemp );
  111.  
  112.                 if( FAILED( D3DXCreateTextureFromFile( pd3dDevice, strTexture, 
  113.                                                        &m_pTextures[i] ) ) )
  114.                     m_pTextures[i] = NULL;
  115.             }
  116.         }
  117.     }
  118.  
  119.     SAFE_RELEASE( pAdjacencyBuffer );
  120.     SAFE_RELEASE( pMtrlBuffer );
  121.  
  122.     return S_OK;
  123. }
  124.  
  125.  
  126.  
  127.  
  128. //-----------------------------------------------------------------------------
  129. // Name:
  130. // Desc:
  131. //-----------------------------------------------------------------------------
  132. HRESULT CD3DMesh::Create( LPDIRECT3DDEVICE8 pd3dDevice,
  133.                           LPDIRECTXFILEDATA pFileData )
  134. {
  135.     LPD3DXBUFFER pMtrlBuffer = NULL;
  136.     LPD3DXBUFFER pAdjacencyBuffer = NULL;
  137.     HRESULT      hr;
  138.  
  139.     // Load the mesh from the DXFILEDATA object
  140.     if( FAILED( hr = D3DXLoadMeshFromXof( pFileData, D3DXMESH_SYSTEMMEM, pd3dDevice,
  141.                                           &pAdjacencyBuffer, &pMtrlBuffer, 
  142.                                           &m_dwNumMaterials, &m_pSysMemMesh ) ) )
  143.     {
  144.         return hr;
  145.     }
  146.  
  147.     // Optimize the mesh for performance
  148.     if( FAILED( hr = m_pSysMemMesh->OptimizeInplace(
  149.                         D3DXMESHOPT_COMPACT | D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_VERTEXCACHE,
  150.                         (DWORD*)pAdjacencyBuffer->GetBufferPointer(), NULL, NULL, NULL ) ) )
  151.     {
  152.         SAFE_RELEASE( pAdjacencyBuffer );
  153.         SAFE_RELEASE( pMtrlBuffer );
  154.         return hr;
  155.     }
  156.  
  157.     // Get material info for the mesh
  158.     // Get the array of materials out of the buffer
  159.     if( pMtrlBuffer && m_dwNumMaterials > 0 )
  160.     {
  161.         // Allocate memory for the materials and textures
  162.         D3DXMATERIAL* d3dxMtrls = (D3DXMATERIAL*)pMtrlBuffer->GetBufferPointer();
  163.         m_pMaterials = new D3DMATERIAL8[m_dwNumMaterials];
  164.         m_pTextures  = new LPDIRECT3DTEXTURE8[m_dwNumMaterials];
  165.  
  166.         // Copy each material and create its texture
  167.         for( DWORD i=0; i<m_dwNumMaterials; i++ )
  168.         {
  169.             // Copy the material
  170.             m_pMaterials[i]         = d3dxMtrls[i].MatD3D;
  171.             m_pMaterials[i].Ambient = m_pMaterials[i].Diffuse;
  172.             m_pTextures[i]          = NULL;
  173.  
  174.             // Create a texture
  175.             if( d3dxMtrls[i].pTextureFilename )
  176.             {
  177.                 TCHAR strTexture[MAX_PATH];
  178.                 TCHAR strTextureTemp[MAX_PATH];
  179.                 DXUtil_ConvertAnsiStringToGeneric( strTextureTemp, d3dxMtrls[i].pTextureFilename );
  180.                 DXUtil_FindMediaFile( strTexture, strTextureTemp );
  181.  
  182.                 if( FAILED( D3DXCreateTextureFromFile( pd3dDevice, strTexture, 
  183.                                                        &m_pTextures[i] ) ) )
  184.                     m_pTextures[i] = NULL;
  185.             }
  186.         }
  187.     }
  188.  
  189.     SAFE_RELEASE( pAdjacencyBuffer );
  190.     SAFE_RELEASE( pMtrlBuffer );
  191.  
  192.     return S_OK;
  193. }
  194.  
  195.  
  196.  
  197.  
  198. //-----------------------------------------------------------------------------
  199. // Name:
  200. // Desc:
  201. //-----------------------------------------------------------------------------
  202. HRESULT CD3DMesh::SetFVF( LPDIRECT3DDEVICE8 pd3dDevice, DWORD dwFVF )
  203. {
  204.     LPD3DXMESH pTempSysMemMesh = NULL;
  205.     LPD3DXMESH pTempLocalMesh  = NULL;
  206.  
  207.     if( m_pSysMemMesh )
  208.     {
  209.         if( FAILED( m_pSysMemMesh->CloneMeshFVF( D3DXMESH_SYSTEMMEM, dwFVF,
  210.                                                  pd3dDevice, &pTempSysMemMesh ) ) )
  211.             return E_FAIL;
  212.     }
  213.     if( m_pLocalMesh )
  214.     {
  215.         if( FAILED( m_pLocalMesh->CloneMeshFVF( 0L, dwFVF, pd3dDevice,
  216.                                                 &pTempLocalMesh ) ) )
  217.         {
  218.             SAFE_RELEASE( pTempSysMemMesh );
  219.             return E_FAIL;
  220.         }
  221.     }
  222.  
  223.     SAFE_RELEASE( m_pSysMemMesh );
  224.     SAFE_RELEASE( m_pLocalMesh );
  225.  
  226.     if( pTempSysMemMesh ) m_pSysMemMesh = pTempSysMemMesh;
  227.     if( pTempLocalMesh )  m_pLocalMesh  = pTempLocalMesh;
  228.  
  229.     // Compute normals in case the meshes have them
  230.     if( m_pSysMemMesh )
  231.         D3DXComputeNormals( m_pSysMemMesh, NULL );
  232.     if( m_pLocalMesh )
  233.         D3DXComputeNormals( m_pLocalMesh, NULL );
  234.  
  235.     return S_OK;
  236. }
  237.  
  238.  
  239.  
  240.  
  241. //-----------------------------------------------------------------------------
  242. // Name:
  243. // Desc:
  244. //-----------------------------------------------------------------------------
  245. HRESULT CD3DMesh::RestoreDeviceObjects( LPDIRECT3DDEVICE8 pd3dDevice )
  246. {
  247.     if( NULL == m_pSysMemMesh )
  248.         return E_FAIL;
  249.  
  250.     // Make a local memory version of the mesh. Note: because we are passing in
  251.     // no flags, the default behavior is to clone into local memory.
  252.     if( FAILED( m_pSysMemMesh->CloneMeshFVF( 0L, m_pSysMemMesh->GetFVF(),
  253.                                              pd3dDevice, &m_pLocalMesh ) ) )
  254.         return E_FAIL;
  255.  
  256.     return S_OK;
  257.  
  258. }
  259.  
  260.  
  261.  
  262.  
  263. //-----------------------------------------------------------------------------
  264. // Name:
  265. // Desc:
  266. //-----------------------------------------------------------------------------
  267. HRESULT CD3DMesh::InvalidateDeviceObjects()
  268. {
  269.     SAFE_RELEASE( m_pLocalMesh );
  270.  
  271.     return S_OK;
  272. }
  273.  
  274.  
  275.  
  276.  
  277. //-----------------------------------------------------------------------------
  278. // Name:
  279. // Desc:
  280. //-----------------------------------------------------------------------------
  281. HRESULT CD3DMesh::Destroy()
  282. {
  283.     InvalidateDeviceObjects();
  284.     for( UINT i=0; i<m_dwNumMaterials; i++ )
  285.         SAFE_RELEASE( m_pTextures[i] );
  286.     SAFE_DELETE_ARRAY( m_pTextures );
  287.     SAFE_DELETE_ARRAY( m_pMaterials );
  288.  
  289.     SAFE_RELEASE( m_pSysMemMesh );
  290.  
  291.     m_dwNumMaterials = 0L;
  292.  
  293.     return S_OK;
  294. }
  295.  
  296.  
  297.  
  298.  
  299. //-----------------------------------------------------------------------------
  300. // Name:
  301. // Desc:
  302. //-----------------------------------------------------------------------------
  303. HRESULT CD3DMesh::Render( LPDIRECT3DDEVICE8 pd3dDevice, BOOL bDrawOpaqueSubsets,
  304.                           BOOL bDrawAlphaSubsets )
  305. {
  306.     if( NULL == m_pLocalMesh )
  307.         return E_FAIL;
  308.  
  309.     // Frist, draw the subsets without alpha
  310.     if( bDrawOpaqueSubsets )
  311.     {
  312.         for( DWORD i=0; i<m_dwNumMaterials; i++ )
  313.         {
  314.             if( m_bUseMaterials )
  315.             {
  316.                 if( m_pMaterials[i].Diffuse.a < 1.0f )
  317.                     continue;
  318.                 pd3dDevice->SetMaterial( &m_pMaterials[i] );
  319.                 pd3dDevice->SetTexture( 0, m_pTextures[i] );
  320.             }
  321.             m_pLocalMesh->DrawSubset( i );
  322.         }
  323.     }
  324.  
  325.     // Then, draw the subsets with alpha
  326.     if( bDrawAlphaSubsets && m_bUseMaterials )
  327.     {
  328.         for( DWORD i=0; i<m_dwNumMaterials; i++ )
  329.         {
  330.             if( m_pMaterials[i].Diffuse.a == 1.0f )
  331.                 continue;
  332.  
  333.             // Set the material and texture
  334.             pd3dDevice->SetMaterial( &m_pMaterials[i] );
  335.             pd3dDevice->SetTexture( 0, m_pTextures[i] );
  336.             m_pLocalMesh->DrawSubset( i );
  337.         }
  338.     }
  339.  
  340.     return S_OK;
  341. }
  342.  
  343.  
  344.  
  345.  
  346. //-----------------------------------------------------------------------------
  347. // Name:
  348. // Desc:
  349. //-----------------------------------------------------------------------------
  350. CD3DFrame::CD3DFrame( TCHAR* strName )
  351. {
  352.     _tcscpy( m_strName, strName );
  353.     D3DXMatrixIdentity( &m_mat );
  354.     m_pMesh  = NULL;
  355.  
  356.     m_pChild = NULL;
  357.     m_pNext  = NULL;
  358. }
  359.  
  360.  
  361.  
  362.  
  363. //-----------------------------------------------------------------------------
  364. // Name:
  365. // Desc:
  366. //-----------------------------------------------------------------------------
  367. CD3DFrame::~CD3DFrame()
  368. {
  369.     SAFE_DELETE( m_pChild );
  370.     SAFE_DELETE( m_pNext );
  371. }
  372.  
  373.  
  374.  
  375.  
  376. //-----------------------------------------------------------------------------
  377. // Name:
  378. // Desc:
  379. //-----------------------------------------------------------------------------
  380. BOOL CD3DFrame::EnumMeshes( BOOL (*EnumMeshCB)(CD3DMesh*,VOID*),
  381.                             VOID* pContext )
  382. {
  383.     if( m_pMesh )
  384.         EnumMeshCB( m_pMesh, pContext );
  385.     if( m_pChild )
  386.         m_pChild->EnumMeshes( EnumMeshCB, pContext );
  387.     if( m_pNext )
  388.         m_pNext->EnumMeshes( EnumMeshCB, pContext );
  389.  
  390.     return TRUE;
  391. }
  392.  
  393.  
  394.  
  395.  
  396. //-----------------------------------------------------------------------------
  397. // Name:
  398. // Desc:
  399. //-----------------------------------------------------------------------------
  400. CD3DMesh* CD3DFrame::FindMesh( TCHAR* strMeshName )
  401. {
  402.     CD3DMesh* pMesh;
  403.  
  404.     if( m_pMesh )
  405.         if( !lstrcmpi( m_pMesh->m_strName, strMeshName ) )
  406.             return m_pMesh;
  407.  
  408.     if( m_pChild )
  409.         if( NULL != ( pMesh = m_pChild->FindMesh( strMeshName ) ) )
  410.             return pMesh;
  411.  
  412.     if( m_pNext )
  413.         if( NULL != ( pMesh = m_pNext->FindMesh( strMeshName ) ) )
  414.             return pMesh;
  415.  
  416.     return NULL;
  417. }
  418.  
  419.  
  420.  
  421.  
  422. //-----------------------------------------------------------------------------
  423. // Name:
  424. // Desc:
  425. //-----------------------------------------------------------------------------
  426. CD3DFrame* CD3DFrame::FindFrame( TCHAR* strFrameName )
  427. {
  428.     CD3DFrame* pFrame;
  429.  
  430.     if( !lstrcmpi( m_strName, strFrameName ) )
  431.         return this;
  432.  
  433.     if( m_pChild )
  434.         if( NULL != ( pFrame = m_pChild->FindFrame( strFrameName ) ) )
  435.             return pFrame;
  436.  
  437.     if( m_pNext )
  438.         if( NULL != ( pFrame = m_pNext->FindFrame( strFrameName ) ) )
  439.             return pFrame;
  440.  
  441.     return NULL;
  442. }
  443.  
  444.  
  445.  
  446.  
  447. //-----------------------------------------------------------------------------
  448. // Name:
  449. // Desc:
  450. //-----------------------------------------------------------------------------
  451. HRESULT CD3DFrame::Destroy()
  452. {
  453.     if( m_pMesh )  m_pMesh->Destroy();
  454.     if( m_pChild ) m_pChild->Destroy();
  455.     if( m_pNext )  m_pNext->Destroy();
  456.  
  457.     SAFE_DELETE( m_pMesh );
  458.     SAFE_DELETE( m_pNext );
  459.     SAFE_DELETE( m_pChild );
  460.  
  461.     return S_OK;
  462. }
  463.  
  464.  
  465.  
  466.  
  467. //-----------------------------------------------------------------------------
  468. // Name:
  469. // Desc:
  470. //-----------------------------------------------------------------------------
  471. HRESULT CD3DFrame::RestoreDeviceObjects( LPDIRECT3DDEVICE8 pd3dDevice )
  472. {
  473.     if( m_pMesh )  m_pMesh->RestoreDeviceObjects( pd3dDevice );
  474.     if( m_pChild ) m_pChild->RestoreDeviceObjects( pd3dDevice );
  475.     if( m_pNext )  m_pNext->RestoreDeviceObjects( pd3dDevice );
  476.     return S_OK;
  477. }
  478.  
  479.  
  480.  
  481.  
  482. //-----------------------------------------------------------------------------
  483. // Name:
  484. // Desc:
  485. //-----------------------------------------------------------------------------
  486. HRESULT CD3DFrame::InvalidateDeviceObjects()
  487. {
  488.     if( m_pMesh )  m_pMesh->InvalidateDeviceObjects();
  489.     if( m_pChild ) m_pChild->InvalidateDeviceObjects();
  490.     if( m_pNext )  m_pNext->InvalidateDeviceObjects();
  491.     return S_OK;
  492. }
  493.  
  494.  
  495.  
  496.  
  497. //-----------------------------------------------------------------------------
  498. // Name:
  499. // Desc:
  500. //-----------------------------------------------------------------------------
  501. HRESULT CD3DFrame::Render( LPDIRECT3DDEVICE8 pd3dDevice, BOOL bDrawOpaqueSubsets,
  502.                            BOOL bDrawAlphaSubsets, D3DXMATRIX* pmatWorldMatrix )
  503. {
  504.     // For pure devices, specify the world transform. If the world transform is not
  505.     // specified on pure devices, this function will fail.
  506.  
  507.     D3DXMATRIX matSavedWorld, matWorld;
  508.  
  509.     if ( NULL == pmatWorldMatrix )
  510.         pd3dDevice->GetTransform( D3DTS_WORLD, &matSavedWorld );
  511.     else
  512.         matSavedWorld = *pmatWorldMatrix;
  513.  
  514.     D3DXMatrixMultiply( &matWorld, &m_mat, &matSavedWorld );
  515.     pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
  516.  
  517.     if( m_pMesh )
  518.         m_pMesh->Render( pd3dDevice, bDrawOpaqueSubsets, bDrawAlphaSubsets );
  519.  
  520.     if( m_pChild )
  521.         m_pChild->Render( pd3dDevice, bDrawOpaqueSubsets, bDrawAlphaSubsets, &matWorld );
  522.  
  523.     pd3dDevice->SetTransform( D3DTS_WORLD, &matSavedWorld );
  524.  
  525.     if( m_pNext )
  526.         m_pNext->Render( pd3dDevice, bDrawOpaqueSubsets, bDrawAlphaSubsets, &matSavedWorld );
  527.  
  528.     return S_OK;
  529. }
  530.  
  531.  
  532.  
  533.  
  534. //-----------------------------------------------------------------------------
  535. // Name:
  536. // Desc:
  537. //-----------------------------------------------------------------------------
  538. HRESULT CD3DFile::LoadFrame( LPDIRECT3DDEVICE8 pd3dDevice,
  539.                              LPDIRECTXFILEDATA pFileData,
  540.                              CD3DFrame* pParentFrame )
  541. {
  542.     LPDIRECTXFILEDATA   pChildData = NULL;
  543.     LPDIRECTXFILEOBJECT pChildObj = NULL;
  544.     const GUID* pGUID;
  545.     DWORD       cbSize;
  546.     CD3DFrame*  pCurrentFrame;
  547.     HRESULT     hr;
  548.  
  549.     // Get the type of the object
  550.     if( FAILED( hr = pFileData->GetType( &pGUID ) ) )
  551.         return hr;
  552.  
  553.     if( *pGUID == TID_D3DRMMesh )
  554.     {
  555.         hr = LoadMesh( pd3dDevice, pFileData, pParentFrame );
  556.         if( FAILED(hr) )
  557.             return hr;
  558.     }
  559.     if( *pGUID == TID_D3DRMFrameTransformMatrix )
  560.     {
  561.         D3DXMATRIX* pmatMatrix;
  562.         hr = pFileData->GetData( NULL, &cbSize, (VOID**)&pmatMatrix );
  563.         if( FAILED(hr) )
  564.             return hr;
  565.  
  566.         // Update the parent's matrix with the new one
  567.         pParentFrame->SetMatrix( pmatMatrix );
  568.     }
  569.     if( *pGUID == TID_D3DRMFrame )
  570.     {
  571.         // Get the frame name
  572.         CHAR  strAnsiName[512] = "";
  573.         TCHAR strName[MAX_PATH];
  574.         DWORD dwNameLength;
  575.         pFileData->GetName( NULL, &dwNameLength );
  576.         if( dwNameLength > 0 )
  577.             pFileData->GetName( strAnsiName, &dwNameLength );
  578.         DXUtil_ConvertAnsiStringToGeneric( strName, strAnsiName );
  579.  
  580.         // Create the frame
  581.         pCurrentFrame = new CD3DFrame( strName );
  582.  
  583.         pCurrentFrame->m_pNext = pParentFrame->m_pChild;
  584.         pParentFrame->m_pChild = pCurrentFrame;
  585.  
  586.         // Enumerate child objects
  587.         while( SUCCEEDED( pFileData->GetNextObject( &pChildObj ) ) )
  588.         {
  589.             // Query the child for its FileData
  590.             hr = pChildObj->QueryInterface( IID_IDirectXFileData,
  591.                                             (VOID**)&pChildData );
  592.             if( SUCCEEDED(hr) )
  593.             {
  594.                 hr = LoadFrame( pd3dDevice, pChildData, pCurrentFrame );
  595.                 pChildData->Release();
  596.             }
  597.  
  598.             pChildObj->Release();
  599.  
  600.             if( FAILED(hr) )
  601.                 return hr;
  602.         }
  603.     }
  604.  
  605.     return S_OK;
  606. }
  607.  
  608.  
  609.  
  610.  
  611. //-----------------------------------------------------------------------------
  612. // Name:
  613. // Desc:
  614. //-----------------------------------------------------------------------------
  615. HRESULT CD3DFile::LoadMesh( LPDIRECT3DDEVICE8 pd3dDevice,
  616.                             LPDIRECTXFILEDATA pFileData,
  617.                             CD3DFrame* pParentFrame )
  618. {
  619.     // Currently only allowing one mesh per frame
  620.     if( pParentFrame->m_pMesh )
  621.         return E_FAIL;
  622.  
  623.     // Get the mesh name
  624.     CHAR  strAnsiName[512] = {0};
  625.     TCHAR strName[MAX_PATH];
  626.     DWORD dwNameLength;
  627.     pFileData->GetName( NULL, &dwNameLength );
  628.     if( dwNameLength > 0 )
  629.         pFileData->GetName( strAnsiName, &dwNameLength );
  630.     DXUtil_ConvertAnsiStringToGeneric( strName, strAnsiName );
  631.  
  632.     // Create the mesh
  633.     pParentFrame->m_pMesh = new CD3DMesh( strName );
  634.     pParentFrame->m_pMesh->Create( pd3dDevice, pFileData );
  635.  
  636.     return S_OK;
  637. }
  638.  
  639.  
  640.  
  641.  
  642. //-----------------------------------------------------------------------------
  643. // Name:
  644. // Desc:
  645. //-----------------------------------------------------------------------------
  646. HRESULT CD3DFile::CreateFromResource( LPDIRECT3DDEVICE8 pd3dDevice, TCHAR* strResource, TCHAR* strType )
  647. {
  648.     LPDIRECTXFILE           pDXFile   = NULL;
  649.     LPDIRECTXFILEENUMOBJECT pEnumObj  = NULL;
  650.     LPDIRECTXFILEDATA       pFileData = NULL;
  651.     HRESULT hr;
  652.  
  653.     // Create a x file object
  654.     if( FAILED( hr = DirectXFileCreate( &pDXFile ) ) )
  655.         return E_FAIL;
  656.  
  657.     // Register templates for d3drm and patch extensions.
  658.     if( FAILED( hr = pDXFile->RegisterTemplates( (VOID*)D3DRM_XTEMPLATES,
  659.                                                  D3DRM_XTEMPLATE_BYTES ) ) )
  660.     {
  661.         pDXFile->Release();
  662.         return E_FAIL;
  663.     }
  664.     
  665.     CHAR strTypeAnsi[MAX_PATH];
  666.     DXUtil_ConvertGenericStringToAnsi( strTypeAnsi, strType );
  667.  
  668.     DXFILELOADRESOURCE dxlr;
  669.     dxlr.hModule = NULL;
  670.     dxlr.lpName = strResource;
  671.     dxlr.lpType = (TCHAR*) strTypeAnsi;
  672.  
  673.     // Create enum object
  674.     hr = pDXFile->CreateEnumObject( (VOID*)&dxlr, DXFILELOAD_FROMRESOURCE, 
  675.                                     &pEnumObj );
  676.     if( FAILED(hr) )
  677.     {
  678.         pDXFile->Release();
  679.         return hr;
  680.     }
  681.  
  682.     // Enumerate top level objects (which are always frames)
  683.     while( SUCCEEDED( pEnumObj->GetNextDataObject( &pFileData ) ) )
  684.     {
  685.         hr = LoadFrame( pd3dDevice, pFileData, this );
  686.         pFileData->Release();
  687.         if( FAILED(hr) )
  688.         {
  689.             pEnumObj->Release();
  690.             pDXFile->Release();
  691.             return E_FAIL;
  692.         }
  693.     }
  694.  
  695.     SAFE_RELEASE( pFileData );
  696.     SAFE_RELEASE( pEnumObj );
  697.     SAFE_RELEASE( pDXFile );
  698.  
  699.     return S_OK;
  700. }
  701.  
  702.  
  703.  
  704.  
  705. //-----------------------------------------------------------------------------
  706. // Name:
  707. // Desc:
  708. //-----------------------------------------------------------------------------
  709. HRESULT CD3DFile::Create( LPDIRECT3DDEVICE8 pd3dDevice, TCHAR* strFilename )
  710. {
  711.     LPDIRECTXFILE           pDXFile   = NULL;
  712.     LPDIRECTXFILEENUMOBJECT pEnumObj  = NULL;
  713.     LPDIRECTXFILEDATA       pFileData = NULL;
  714.     HRESULT hr;
  715.  
  716.     // Create a x file object
  717.     if( FAILED( hr = DirectXFileCreate( &pDXFile ) ) )
  718.         return E_FAIL;
  719.  
  720.     // Register templates for d3drm and patch extensions.
  721.     if( FAILED( hr = pDXFile->RegisterTemplates( (VOID*)D3DRM_XTEMPLATES,
  722.                                                  D3DRM_XTEMPLATE_BYTES ) ) )
  723.     {
  724.         pDXFile->Release();
  725.         return E_FAIL;
  726.     }
  727.  
  728.     // Find the path to the file, and convert it to ANSI (for the D3DXOF API)
  729.     TCHAR strPath[MAX_PATH];
  730.     CHAR  strPathANSI[MAX_PATH];
  731.     DXUtil_FindMediaFile( strPath, strFilename );
  732.     DXUtil_ConvertGenericStringToAnsi( strPathANSI, strPath );
  733.     
  734.     // Create enum object
  735.     hr = pDXFile->CreateEnumObject( (VOID*)strPathANSI, DXFILELOAD_FROMFILE, 
  736.                                     &pEnumObj );
  737.     if( FAILED(hr) )
  738.     {
  739.         pDXFile->Release();
  740.         return hr;
  741.     }
  742.  
  743.     // Enumerate top level objects (which are always frames)
  744.     while( SUCCEEDED( pEnumObj->GetNextDataObject( &pFileData ) ) )
  745.     {
  746.         hr = LoadFrame( pd3dDevice, pFileData, this );
  747.         pFileData->Release();
  748.         if( FAILED(hr) )
  749.         {
  750.             pEnumObj->Release();
  751.             pDXFile->Release();
  752.             return E_FAIL;
  753.         }
  754.     }
  755.  
  756.     SAFE_RELEASE( pFileData );
  757.     SAFE_RELEASE( pEnumObj );
  758.     SAFE_RELEASE( pDXFile );
  759.  
  760.     return S_OK;
  761. }
  762.  
  763.  
  764.  
  765.  
  766. //-----------------------------------------------------------------------------
  767. // Name:
  768. // Desc:
  769. //-----------------------------------------------------------------------------
  770. HRESULT CD3DFile::Render( LPDIRECT3DDEVICE8 pd3dDevice, D3DXMATRIX* pmatWorldMatrix )
  771. {
  772.  
  773.     // For pure devices, specify the world transform. If the world transform is not
  774.     // specified on pure devices, this function will fail.
  775.  
  776.     // Set up the world transformation
  777.     D3DXMATRIX matSavedWorld, matWorld;
  778.  
  779.     if ( NULL == pmatWorldMatrix )
  780.         pd3dDevice->GetTransform( D3DTS_WORLD, &matSavedWorld );
  781.     else
  782.         matSavedWorld = *pmatWorldMatrix;
  783.  
  784.     D3DXMatrixMultiply( &matWorld, &matSavedWorld, &m_mat );
  785.     pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
  786.  
  787.     // Render opaque subsets in the meshes
  788.     if( m_pChild )
  789.         m_pChild->Render( pd3dDevice, TRUE, FALSE, &matWorld );
  790.  
  791.     // Enable alpha blending
  792.     pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
  793.     pd3dDevice->SetRenderState( D3DRS_SRCBLEND,  D3DBLEND_SRCALPHA );
  794.     pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
  795.  
  796.     // Render alpha subsets in the meshes
  797.     if( m_pChild )
  798.         m_pChild->Render( pd3dDevice, FALSE, TRUE, &matWorld );
  799.  
  800.     // Restore state
  801.     pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
  802.     pd3dDevice->SetTransform( D3DTS_WORLD, &matSavedWorld );
  803.  
  804.     return S_OK;
  805. }
  806.  
  807.  
  808.  
  809.  
  810.